
using System;
using System.Drawing;
using System.Globalization;
using Microsoft.VisualStudio.Modeling;
using Microsoft.VisualStudio.Modeling.Design;

namespace DslCrossModelFramework {
    public class ModelClass {

        /// <summary>
        /// Initializes a new instance of the <see cref="ModelClass"/> class.
        /// </summary>
        /// <param name="classInfo">The class info.</param>
        public ModelClass(DomainClassInfo classInfo, DomainClassInfo rootClassInfo) {
            this.classId = GetDomainObjectGuid(classInfo.ImplementationClass);
            this.className = classInfo.Name;
            this.displayName = GetDomainObjectDisplayName(classInfo.ImplementationClass);
            this.rootClassInfo = rootClassInfo;
        }

        ///// <summary>
        ///// Initializes a new instance of the <see cref="ModelClass"/> class.
        ///// </summary>
        ///// <param name="type">The domain class type.</param>
        //public ModelClass(Type type) {
        //    this.classId = GetDomainObjectGuid(type);
        //    this.className = type.Name;
        //    this.displayName = GetDomainObjectDisplayName(type);
        //}

        /// <summary>
        /// Gets the name of the class.
        /// </summary>
        /// <value>The name of the class.</value>
        public string ClassName {
            get { return className;}
        }
        private readonly string className;

        /// <summary>
        /// Gets the class id.
        /// </summary>
        /// <value>The class id.</value>
        public Guid ClassId {
            get { return classId; }
        }
        private readonly Guid classId;


        /// <summary>
        /// Gets the display name.
        /// </summary>
        /// <value>The display name.</value>
        public string DisplayName {
            get { return displayName; }
        }
        private string displayName;

        public bool SerializesId {
            get { return serializesId; }
            set { serializesId = value; }
        }
        private bool serializesId;

        public bool HasMonikerKey {
            get { return hasMonikerKey; }
            set { hasMonikerKey = value; }
        }
        private bool hasMonikerKey;

        public bool HasElementName {
            get { return hasElementName; }
            set { hasElementName = value; }
        }
        private bool hasElementName;

        public DomainClassInfo RootClassInfo {
            get { return rootClassInfo; }
        }
        private readonly DomainClassInfo rootClassInfo;

        /// <summary>
        /// Gets the display name of the domain object.
        /// </summary>
        /// <param name="domainModelType">Type of the domain model.</param>
        /// <returns></returns>
        internal static string GetDomainObjectDisplayName(Type domainModelType) {
            if (domainModelType == null) {
                throw new ArgumentNullException("domainModelType");
            }
            object[] customAttributes = domainModelType.GetCustomAttributes(typeof(DisplayNameResourceAttribute), true);
            if (customAttributes.Length <= 0) {
                //TODO: throw proper exception
                throw new ArgumentException("Cannot get domainobjectdisplayname");
            }
            return ((DisplayNameResourceAttribute)customAttributes.GetValue(0)).DisplayName;
        }

        /// <summary>
        /// Gets the domain object GUID.
        /// </summary>
        /// <param name="domainModelType">Type of the domain model.</param>
        /// <returns></returns>
        internal static Guid GetDomainObjectGuid(Type domainModelType) {
            if (domainModelType == null) {
                throw new ArgumentNullException("domainModelType");
            }
            object[] customAttributes = domainModelType.GetCustomAttributes(typeof(DomainObjectIdAttribute), true);
            if (customAttributes.Length <= 0) {
                //TODO: throw proper exception
                throw new ArgumentException("Cannot get DomainObjectGuid");
            }
            return ((DomainObjectIdAttribute)customAttributes.GetValue(0)).Id;
        }
    }
}